//
//  ParserToNET.java
//  TopoManipApplet
//
//  Created by Thibaud PIQUET on 09/04/10.
//  Copyright 2010 __MyCompanyName__. All rights reserved.
//

package src.convertisseur;
import java.util.*;
import java.io.*;
import org.jdom.*;
import javax.xml.transform.Source;
import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.*;
import org.xml.sax.SAXException;
import java.net.*;

/**
 *
 * @author Thibaud PIQUET
 */
public class ParserToNET implements Runnable{
	
    File ftp; // File to parse
	File fileOut;  // File to create
    Writer fw; // File Writer
    BufferedWriter bw; // Buffer Writer
    String line;
    String chaine;
    String[] res;
	
    public ParserToNET(File file, File fileOUT) throws IOException {
        this.ftp = file;
		this.fileOut = fileOUT;
        this.fw = new FileWriter(this.fileOut);
        this.bw = new BufferedWriter(this.fw);
    }
	
	public void run() {
		try {
			this.parseToNET();
		}
		catch (Exception e) {
			e.printStackTrace();
			Resume result = Resume.getInstance();
			result.add("ParserToNET","procedure run had some problems : "+e);
		}
	}

	public void parseToNET() throws IOException {
		
		Element domain;
		Element topology;
		Element nodes;
		Element links;
		
		Resume result = Resume.getInstance();

        try {
			
            // ****************************************************************************************************
            // Default values for NET if there aren't in the XML file
            // -- Arc & Edge
            // if there is not information about simplex or duplex in the XML file, links are considered as arcs
            // weight : 1
            // ****************************************************************************************************
			
			/************************************************************ Loading default values *************************************************************/
			InputStream inDefaultValues = getClass().getResourceAsStream("/resources/configuration.xml");
			
			org.jdom.input.SAXBuilder builderConfig = new org.jdom.input.SAXBuilder();
            builderConfig.setIgnoringElementContentWhitespace(true);
            org.jdom.Document documentDefaultValues = builderConfig.build(inDefaultValues);
			
			Element defaultValues = documentDefaultValues.getRootElement();
			
			String defaultValue_Link_weight="";
			
			List listOfFormats = defaultValues.getChildren();
			Iterator ilistOfFormats = listOfFormats.iterator();
			while(ilistOfFormats.hasNext()){
				Element currentChildOfDefaultValues = (Element)ilistOfFormats.next();
				
				if(currentChildOfDefaultValues.toString().equals("[Element: <format/>]")) {
					
					if(currentChildOfDefaultValues.getAttributeValue("name").equals("NET")){
						
						List listOfDefaultValuesOfFormat = currentChildOfDefaultValues.getChildren();
						Iterator ilistOfDefaultValuesOfFormat = listOfDefaultValuesOfFormat.iterator();
						while(ilistOfDefaultValuesOfFormat.hasNext()){
							Element currentChildOfFormat = (Element)ilistOfDefaultValuesOfFormat.next();
							
							if(currentChildOfFormat.toString().equals("[Element: <link/>]")){
								
								List listOfChildOfNode = currentChildOfFormat.getChildren();
								Iterator ilistOfChildOfNode = listOfChildOfNode.iterator();
								while(ilistOfChildOfNode.hasNext()){
									Element currentUnit = (Element)ilistOfChildOfNode.next();
									
									if(currentUnit.toString().equals("[Element: <unit/>]")){
										
										if(currentUnit.getAttributeValue("type").equals("weight")){
											defaultValue_Link_weight=currentUnit.getAttributeValue("value");
										}											
									}
								}
							}
						}
					}
				}
			}				
			/*************************************************************************************************************************************************/
			
            org.jdom.input.SAXBuilder builder = new org.jdom.input.SAXBuilder();
            builder.setIgnoringElementContentWhitespace(true);
            org.jdom.Document document = builder.build(ftp);
			
            domain = document.getRootElement();
			
            /* Test to know domain's sons */
            boolean BoolTopology = false;
			
            List domainChildren = domain.getChildren();
            Iterator idomainChildren = domainChildren.iterator();
            while(idomainChildren.hasNext()) {
                Element currentChild = (Element)idomainChildren.next();
                if(currentChild.toString().equals("[Element: <topology/>]")) { BoolTopology=true; }
            }
			
            if(BoolTopology==true){
                topology = domain.getChild("topology");
                nodes = topology.getChild("nodes");
                links = topology.getChild("links");
				
                int NbNodes = nodes.getChildren().size();
				
                /* Nodes */
                bw.write("*Vertices\t"+NbNodes);
                bw.newLine();
				
                String idNode="";
				
                List listOfNode = nodes.getChildren();
                Iterator ilistOfNode = listOfNode.iterator();
                while(ilistOfNode.hasNext()){
                    Element currentNode = (Element)ilistOfNode.next();
                    
                    idNode = currentNode.getAttributeValue("id");
					
                    bw.write("\t"+idNode);
                    bw.newLine();
                }
				
                /* Links */
				
                String idLink="", srcNode="", tgtNode="", weight="", linkType="";
                boolean arcExists=false, edgeExists=false;
				
                /* Test to know what kind of link : arc or edge (equivalent to simplex & duplex) */
                List listOfLinkForArc = links.getChildren();
                Iterator ilistOfLinkForArc = listOfLinkForArc.iterator();
                while(ilistOfLinkForArc.hasNext()){
                    Element currentLinkForArc = (Element)ilistOfLinkForArc.next();
					
                    List listOfChildOfLink = currentLinkForArc.getChildren();
                    Iterator ilistOfChildOfLink = listOfChildOfLink.iterator();
                    while(ilistOfChildOfLink.hasNext()){
                        Element currentChildLink = (Element)ilistOfChildOfLink.next();
						
                        if(currentChildLink.toString().equals("[Element: <linkType/>]")){
                            List listOfAttributesOfType = currentChildLink.getAttributes();
                            Iterator ilistOfAttributesOfType = listOfAttributesOfType.iterator();
                            while(ilistOfAttributesOfType.hasNext()){
                                Attribute currentAttributeType = (Attribute)ilistOfAttributesOfType.next();
								
                                if(currentAttributeType.getName().equals("type1")){
                                    if(currentAttributeType.getValue().equals("simplex")) {
                                        arcExists=true;
                                    }
                                    else if(currentAttributeType.getValue().equals("duplex")) {
                                        edgeExists=true;
                                    }
                                    else {
                                        arcExists=true;
                                    }
                                }
                                else {
                                    arcExists=true;
                                }
                            }
                        }
                        else{
                            arcExists=true;
                        }
                    }
                }
				
                if(arcExists==true){
					bw.write("*Arcs");
					bw.newLine();
					
                    List listOfLink = links.getChildren();
                    Iterator ilistOfLink = listOfLink.iterator();
                    while(ilistOfLink.hasNext()){
                        Element currentLink = (Element)ilistOfLink.next();
						
                        List listOfChildOfLink = currentLink.getChildren();
                        Iterator ilistOfChildOfLink = listOfChildOfLink.iterator();
                        while(ilistOfChildOfLink.hasNext()){
                            Element currentChildLink = (Element)ilistOfChildOfLink.next();
							
                            if(currentChildLink.toString().equals("[Element: <source/>]")){
                                List listOfAttributeSource = currentChildLink.getAttributes();
                                Iterator ilistOfAttributeSource = listOfAttributeSource.iterator();
                                while(ilistOfAttributeSource.hasNext()){
                                    Attribute currentAttributeSource = (Attribute)ilistOfAttributeSource.next();
									
                                    if(currentAttributeSource.getName().equals("node")){
                                        srcNode = currentAttributeSource.getValue();
                                    }
                                }
                            }
							
                            else if(currentChildLink.toString().equals("[Element: <target/>]")){
                                List listOfAttributeTarget = currentChildLink.getAttributes();
                                Iterator ilistOfAttributeTarget = listOfAttributeTarget.iterator();
                                while(ilistOfAttributeTarget.hasNext()){
                                    Attribute currentAttributeTarget = (Attribute)ilistOfAttributeTarget.next();
									
                                    if(currentAttributeTarget.getName().equals("node")){
                                        tgtNode = currentAttributeTarget.getValue();
                                    }
                                }
                            }
							
                            else if(currentChildLink.toString().equals("[Element: <weight/>]")){
                                weight = currentChildLink.getValue();
                            }
							
                            else if(currentChildLink.toString().equals("[Element: <linkType/>]")){
                                List listOfAttributesOfType = currentChildLink.getAttributes();
                                Iterator ilistOfAttributesOfType = listOfAttributesOfType.iterator();
                                while(ilistOfAttributesOfType.hasNext()){
                                    Attribute currentAttributeType = (Attribute)ilistOfAttributesOfType.next();
									
                                    if(currentAttributeType.getName().equals("type1")){
                                        if(currentAttributeType.getValue().equals("simplex")) {
                                            linkType = "arc";
                                        }
                                    }
                                }
                            }
                            else {
                                linkType = "arc";
                            }
                        }
						
                        /* Assignement of default value*/
                        if(weight.equals("")){
                            weight=defaultValue_Link_weight;
                        }
						
                        if(linkType.equals("arc")){
                            bw.write("\t"+srcNode+"\t"+tgtNode+"\t"+weight);
                            bw.newLine();
                        }
                    }
                }
				
                if(edgeExists==true){
                    bw.write("*Edges");
                    bw.newLine();
					
                    List listOfLink = links.getChildren();
                    Iterator ilistOfLink = listOfLink.iterator();
                    while(ilistOfLink.hasNext()){
                        Element currentLink = (Element)ilistOfLink.next();
						
                        List listOfChildOfLink = currentLink.getChildren();
                        Iterator ilistOfChildOfLink = listOfChildOfLink.iterator();
                        while(ilistOfChildOfLink.hasNext()){
                            Element currentChildLink = (Element)ilistOfChildOfLink.next();
							
                            if(currentChildLink.toString().equals("[Element: <source/>]")){
                                List listOfAttributeSource = currentChildLink.getAttributes();
                                Iterator ilistOfAttributeSource = listOfAttributeSource.iterator();
                                while(ilistOfAttributeSource.hasNext()){
                                    Attribute currentAttributeSource = (Attribute)ilistOfAttributeSource.next();
									
                                    if(currentAttributeSource.getName().equals("node")){
                                        srcNode = currentAttributeSource.getValue();
                                    }
                                }
                            }
							
                            if(currentChildLink.toString().equals("[Element: <target/>]")){
                                List listOfAttributeTarget = currentChildLink.getAttributes();
                                Iterator ilistOfAttributeTarget = listOfAttributeTarget.iterator();
                                while(ilistOfAttributeTarget.hasNext()){
                                    Attribute currentAttributeTarget = (Attribute)ilistOfAttributeTarget.next();
									
                                    if(currentAttributeTarget.getName().equals("node")){
                                        tgtNode = currentAttributeTarget.getValue();
                                    }
                                }
                            }
							
                            if(currentChildLink.toString().equals("[Element: <weight/>]")){
                                weight = currentChildLink.getValue();
                            }
							
                            if(currentChildLink.toString().equals("[Element: <linkType/>]")){
                                List listOfAttributesOfType = currentChildLink.getAttributes();
                                Iterator ilistOfAttributesOfType = listOfAttributesOfType.iterator();
                                while(ilistOfAttributesOfType.hasNext()){
                                    Attribute currentAttributeType = (Attribute)ilistOfAttributesOfType.next();
									
                                    if(currentAttributeType.getName().equals("type1")){
                                        if(currentAttributeType.getValue().equals("duplex")) {
                                            linkType = "edge";
                                        }
                                    }
                                }
                            }
                        }
						
                        /* Assignement of default value*/
                        if(weight.equals("")){
                            weight=defaultValue_Link_weight;
                        }
						
                        if(linkType.equals("edge")){
                            bw.write("\t"+srcNode+"\t"+tgtNode+"\t"+weight);
                            bw.newLine();
                        }
                    }
                }
            }
            bw.close();
            fw.close();
			result.add("ParserToNET","Export succeeded");
			
		} catch (Exception e) {
			e.printStackTrace();
			result.add("ParserToNET","Export had problems "+e);
		}
    }
}